package repository;

import fileoperation.FileCreation;
import fileoperation.FileDeletion;
import index.Index;

import java.io.File;
import java.io.IOException;

/**
 * Todo: Add your own code. JitInit.init("worktree") should be able to create a repository "worktree/.jit" ,
 *       which contains all the default files and other repositories inside. If the repository has
 *       already exists, delete the former one and create a new one. You're welcome to reconstruct the code,
 *       but don't change the code in the core directory.
 */
public class Repository {
    // 工作区路径
    private static String workTree;
    // 工作区下的.jit版本库路径
    private static String gitDir;
    // 暂存区路径
    private static String gitIndex;

    /**
     * Constructor
     */
    public Repository() throws IOException {
        if(gitDir == ""){
            throw new IOException("The repository does not exist!");
        }
    }
    
    /**
     * Construct a new repository instance with certain path.
     * Constructor
     * @param path
     * @throws IOException
     */
    public Repository(String path) throws IOException {
        this.workTree = path;
        this.gitDir = path + File.separator + ".jit";
        this.gitIndex = path + File.separator + ".jit" + File.separator + "index";
    }

    public static String getGitDir() {
        return gitDir;
    }

    public static String getWorkTree() {
        return workTree;
    }

    public static String getGitIndex() {
        return gitIndex;
    }
    
    /**
     * Helper functions.
     * @return
     */
    public boolean exist(){ return new File(gitDir).exists(); }

    public boolean isFile(){ return new File(gitDir).isFile(); }

    public boolean isDirectory(){ return new File(gitDir).isDirectory(); }


    /**
     * Create the repository and files and directories inside.
     * @return boolean
     * @throws IOException
     */
    public void createRepo() throws IOException {
        /* Todo：Add your code here. */
        /*
         * 需要创建的目录如下
         * |-.jit
         *   |- hooks
         *   |- info
         *   |- objects
         *     |- info
         *     |- pack
         * |- logs
         *   |- refs
         *      |-  heads(本地分支信息)
         *        |-  master(文件)：记录本地master分支的commit信息
         *        |-  localBranchDemo(文件)：记录本地localBranchDemo分支的commit信息
         *      |-  remote(远程分支信息)
         *       |-  master(文件)：记录远程master分支的commit信息）
         *        |-  remoteBranchDemo(文件)：记录远程remoteBranchDemo分支的commit信息）
         *   |- HEAD(文件):记录本地全部分支的commit信息(切换分支时，父子的commitId都是自己)
         *   |- refs
         *     |- heads
         *     |- tags
         *   |- config （文件）
         *   |- description （文件）
         *   |- HEAD （文件）
         *   |- index （文件夹）      【待建】
         * */
        // 需要在工作区路径下创建.jit文件夹
        FileCreation.createDirectory(workTree, ".jit");
        // 在.jit文件目录下创建hooks文件夹
        FileCreation.createDirectory(gitDir, "hooks");
        // 在.jit文件目录下创建info文件夹
        FileCreation.createDirectory(gitDir, "info");
        // 在.jit文件目录下创建objects文件夹
        // objects实际保存了blob，tree，commit对象的hash文件，即是一个jit存储项目版本文件的地方
        FileCreation.createDirectory(gitDir, "objects");
        // 在.jit文件目录下创建refs文件夹
        // refs里存储着创建的不同分支的具体信息
        FileCreation.createDirectory(gitDir, "refs");
        // 在refs文件目录下创建heads文件夹
        FileCreation.createDirectory(gitDir, "refs", "heads");
        // 在refs文件目录下创建tags文件夹
        FileCreation.createDirectory(gitDir, "refs", "tags");
        // 在refs/heads内创建master文件
//        FileCreation.createFile(gitDir+File.separator+"refs"+File.separator+"heads", "master"  , "");
        // 在.jit文件目录下创建logs文件夹
        // logs存储了不同分支下的commit记录，可以用于commit回滚以及历史commit的查看
//        FileCreation.createDirectory(gitDir, "logs");
//         在logs文件目录下创建refs文件夹
//        FileCreation.createDirectory(gitDir, "logs", "refs");
//         在logs文件目录下的refs文件夹里，创建heads文件夹
//        FileCreation.createDirectory(gitDir, "logs", "refs", "heads");
//         在logs文件目录下的refs文件夹里的heads文件夹里，创建master文件：记录本地master分支的commit信息
//        FileCreation.createDirectory(gitDir, "logs","refs", "remotes");
//         在logs文件目录下的refs文件夹里，创建remote文件夹
//        FileCreation.createDirectory(gitDir, "logs","refs", "remotes");
//         在logs文件目录下的refs文件夹里的remote文件夹里，创建master文件：记录远程master分支的commit信息
//        FileCreation.createDirectory(gitDir, "logs","refs", "remotes");
//         在logs文件夹里，创建名为"Head"的空文件
//        FileCreation.createFile(gitDir + File.separator + "logs", "Head", "");
        // 在.jit文件目录下创建名为"config"的文件，内容如下，记录jit的初始配置
        FileCreation.createFile(gitDir, "config", "[core]\n" +
                "\trepositoryformatversion = 0\n" +
                "\tfilemode = false\n" +
                "\tbare = false\n" +
                "\tlogallrefupdates = true\n" +
                "\tsymlinks = false\n" +
                "\tignorecase = true");
        // 在.jit文件目录下创建名为"HEAD"的文件，内容如下，存储着当前的HEAD指针指向的分支（branch）
//        FileCreation.createFile(gitDir, "HEAD", "ref: refs/heads/master");
        FileCreation.createFile(gitDir, "HEAD", "");
        // 在.jit文件目录下创建名为"description"的文件，存储着对仓库的描述，内容如下
        FileCreation.createFile(gitDir, "description", "Unnamed repository; edit this file 'description' to name the repository.");
        // 在.jit文件目录下创建名为"index"的空文件
//         index是git中的暂存区，用来临时存储通过git add添加的文件。当commit之后暂存区会被清空。
//        FileCreation.createFile(gitDir, "index", "");
    }

    public static void clearRepo(){
        File repo = new File(Repository.getWorkTree());
        File[] fs = repo.listFiles();
        for(int i =0; i<fs.length ;i++){
            if(!fs[i].getName().contains(".jit")){
                FileDeletion.deleteFile(fs[i].getPath());
            }
        }
    }
}
